package ltd.nullpointer.tcp.core.message;

import com.boot2.core.utils.ByteUtils;
import io.netty.buffer.ByteBuf;
import org.apache.commons.lang3.ArrayUtils;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

/**
 * 
 * @ClassName: AbstractTCPMessage.java
 * @Description: tcp报文消息基类
 * @author zhangweilin
 * @date 2018年1月19日 下午4:03:50
 *
 */
public class AbstractTCPMessage<T> extends BaseMessage<T> {
	/**
	 * 
	 */
	private static final long serialVersionUID = -8272831117358519137L;

	/**
	 * 消息头,约定保留五位头
	 */
	protected byte[] header = new byte[] {};

	/**
	 * 原始的报文字节
	 */
	protected byte[] payloadByte = new byte[] {};

	/**
	 * 消息尾
	 */
	protected byte[] tail = new byte[] {};

	/**
	 * 来自netty中原始字节缓冲区
	 */
	protected ByteBuf in;

	/**
	 * 原始报文的字节长度
	 */
	protected int payloadByteLength;

	/**
	 * 原始报文的字符串长度
	 */
	protected int payloadLength;

	/**
	 * 消息来源ip
	 */
	protected String ip;

	/**
	 * 消息来源设备id,可能是硬件，可能是app,可能是云端
	 */
	protected String deviceSn;

	/**
	 * 如果字节没值，但是字符有值，则返回字符的字节
	 * 
	 * @return
	 */
	public byte[] getPayloadByte() {
		if (ArrayUtils.isNotEmpty(payloadByte)) {
			return this.payloadByte;
		}
		if (null != payload && (payload instanceof String)) {
			try {
				String payload0 = (String) payload;
				return payload0.getBytes("UTF-8");
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return this.payloadByte;
	}

	/**
	 * 如果字符不为空返回字符，否则返回字节对应的字符
	 * 
	 * @return
	 */
	@Override
	public T getPayload() {
		if (null != payload) {
			return payload;
		}
//		if (ArrayUtils.isNotEmpty(payloadByte) && (payload instanceof String)) {
//			// return ByteUtils.byteArr2HexStr(payloadByte);
//			return ByteUtils.getString(payloadByte);
//		}
		return payload;
	}

	public int getPayloadByteLength() {
		return getPayloadByte().length;
	}

	// public int getPayloadLength() {
	// return getPayload().byteLength();
	// }

	@Override
	public String toString() {
		// String headerStr = ByteUtils.byteArr2HexStr(getHeader());
		String headerStr = ByteUtils.getString(getHeader());
		String payloadByteStr0 = Arrays.toString(getPayloadByte());
		Object payload0 = getPayload();
		// String tailStr = ByteUtils.byteArr2HexStr(getTail());
		String tailStr = ByteUtils.getString(getTail());
		return "header:" + headerStr + " ,payloadByte:" + payloadByteStr0 + " ,payload:" + payload0 + ", tail: " + tailStr;
	}

	public byte[] getHeader() {
		return header;
	}

	public void setHeader(byte[] header) {
		this.header = header;
	}

	public byte[] getTail() {
		return tail;
	}

	public void setTail(byte[] tail) {
		this.tail = tail;
	}

	public ByteBuf getIn() {
		return in;
	}

	public void setIn(ByteBuf in) {
		this.in = in;
	}

	public String getIp() {
		return ip;
	}

	public void setIp(String ip) {
		this.ip = ip;
	}

	public String getDeviceSn() {
		return deviceSn;
	}

	public void setDeviceSn(String deviceSn) {
		this.deviceSn = deviceSn;
	}

	public void setPayloadByte(byte[] payloadByte) {
		this.payloadByte = payloadByte;
	}

	@Override
	public void setPayload(T payload) {
		if (null == getMsgCode()) {
			if (payload instanceof AbstractNPiotMessage) {
				AbstractNPiotMessage abstractNPiotMessage = (AbstractNPiotMessage) payload;
				String msgCode = abstractNPiotMessage.getMsgCode();
				if (null == msgCode) {
					// throw new IllegalArgumentException("msgCode can not be null");
//					throw new MessageResolverException(TCPEnum.ErrorCode.err10011.getErrCode(), TCPEnum.ErrorCode.err10011.getName());
				} else {
					setMsgCode(msgCode);
				}
			} else {
			}
		}
		this.payload = payload;
	}

	public void setPayloadByteLength(int payloadByteLength) {
		this.payloadByteLength = payloadByteLength;
	}

	public void setPayloadLength(int payloadLength) {
		this.payloadLength = payloadLength;
	}
}
